home *** CD-ROM | disk | FTP | other *** search
/ Openstep 4.2 (Developer) / Openstep Developer 4.2.iso / NextDeveloper / Source / GNU / uucp / Uucp.framework / unix.subproj / trunc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-09  |  3.2 KB  |  158 lines

  1. /* trunc.c
  2.    Truncate a file to zero length.  */
  3.  
  4. #include "uucp.h"
  5.  
  6. #include "uudefs.h"
  7. #include "sysdep.h"
  8. #include "system.h"
  9.  
  10. #include <errno.h>
  11.  
  12. #if HAVE_FCNTL_H
  13. #include <fcntl.h>
  14. #else
  15. #if HAVE_SYS_FILE_H
  16. #include <sys/file.h>
  17. #endif
  18. #endif
  19.  
  20. #ifndef FD_CLOEXEC
  21. #define FD_CLOEXEC 1
  22. #endif
  23.  
  24. #ifndef SEEK_SET
  25. #define SEEK_SET 0
  26. #endif
  27.  
  28. /* External functions.  */
  29. #ifndef lseek
  30. extern off_t lseek ();
  31. #endif
  32.  
  33. /* Truncate a file to zero length.  If this fails, it closes and
  34.    removes the file.  We support a number of different means of
  35.    truncation, which is probably a waste of time since this function
  36.    is currently only called when the 'f' protocol resends a file.  */
  37.  
  38. #if HAVE_FTRUNCATE
  39. #undef HAVE_LTRUNC
  40. #define HAVE_LTRUNC 0
  41. #endif
  42.  
  43. #if ! HAVE_FTRUNCATE && ! HAVE_LTRUNC
  44. #ifdef F_CHSIZE
  45. #define HAVE_F_CHSIZE 1
  46. #else /* ! defined (F_CHSIZE) */
  47. #ifdef F_FREESP
  48. #define HAVE_F_FREESP 1
  49. #endif /* defined (F_FREESP) */
  50. #endif /* ! defined (F_CHSIZE) */
  51. #endif /* ! HAVE_FTRUNCATE && ! HAVE_LTRUNC */
  52.  
  53. openfile_t
  54. esysdep_truncate (e, zname)
  55.      openfile_t e;
  56.      const char *zname;
  57. {
  58.   int o;
  59.  
  60. #if HAVE_FTRUNCATE || HAVE_LTRUNC || HAVE_F_CHSIZE || HAVE_F_FREESP
  61.   int itrunc;
  62.  
  63.   if (! ffilerewind (e))
  64.     {
  65.       ulog (LOG_ERROR, "rewind: %s", strerror (errno));
  66.       (void) ffileclose (e);
  67.       (void) remove (zname);
  68.       return EFILECLOSED;
  69.     }
  70.  
  71. #if USE_STDIO
  72.   o = fileno (e);
  73. #else
  74.   o = e;
  75. #endif
  76.  
  77. #if HAVE_FTRUNCATE
  78.   itrunc = ftruncate (o, 0);
  79. #endif
  80. #if HAVE_LTRUNC
  81.   itrunc = ltrunc (o, (long) 0, SEEK_SET);
  82. #endif
  83. #if HAVE_F_CHSIZE
  84.   itrunc = fcntl (o, F_CHSIZE, (off_t) 0);
  85. #endif
  86. #if HAVE_F_FREESP
  87.   /* This selection is based on an implementation of ftruncate by
  88.      kucharsk@Solbourne.com (William Kucharski).  */
  89.   {
  90.     struct flock fl;
  91.  
  92.     fl.l_whence = 0;
  93.     fl.l_len = 0;
  94.     fl.l_start = 0;
  95.     fl.l_type = F_WRLCK;
  96.  
  97.     itrunc = fcntl (o, F_FREESP, &fl);
  98.   }
  99. #endif
  100.  
  101.   if (itrunc != 0)
  102.     {
  103. #if HAVE_FTRUNCATE
  104.       ulog (LOG_ERROR, "ftruncate: %s", strerror (errno));
  105. #endif
  106. #ifdef HAVE_LTRUNC
  107.       ulog (LOG_ERROR, "ltrunc: %s", strerror (errno));
  108. #endif
  109. #ifdef HAVE_F_CHSIZE
  110.       ulog (LOG_ERROR, "fcntl (F_CHSIZE): %s", strerror (errno));
  111. #endif
  112. #ifdef HAVE_F_FREESP
  113.       ulog (LOG_ERROR, "fcntl (F_FREESP): %s", strerror (errno));
  114. #endif
  115.  
  116.       (void) ffileclose (e);
  117.       (void) remove (zname);
  118.       return EFILECLOSED;
  119.     }
  120.  
  121.   return e;
  122. #else /* ! (HAVE_FTRUNCATE || HAVE_LTRUNC || HAVE_F_CHSIZE || HAVE_F_FREESP) */
  123.   (void) ffileclose (e);
  124.   (void) remove (zname);
  125.  
  126.   o = creat ((char *) zname, IPRIVATE_FILE_MODE);
  127.  
  128.   if (o == -1)
  129.     {
  130.       ulog (LOG_ERROR, "creat (%s): %s", zname, strerror (errno));
  131.       return EFILECLOSED;
  132.     }
  133.  
  134.   if (fcntl (o, F_SETFD, fcntl (o, F_GETFD, 0) | FD_CLOEXEC) < 0)
  135.     {
  136.       ulog (LOG_ERROR, "fcntl (FD_CLOEXEC): %s", strerror (errno));
  137.       (void) close (o);
  138.       return EFILECLOSED;
  139.     }
  140.  
  141. #if USE_STDIO
  142.   e = fdopen (o, (char *) BINWRITE);
  143.  
  144.   if (e == NULL)
  145.     {
  146.       ulog (LOG_ERROR, "fdopen (%s): %s", zname, strerror (errno));
  147.       (void) close (o);
  148.       (void) remove (zname);
  149.       return NULL;
  150.     }
  151. #else /* ! USE_STDIO */
  152.   e = o;
  153. #endif /* ! USE_STDIO */
  154.  
  155.   return e;
  156. #endif /* ! (HAVE_FTRUNCATE || HAVE_LTRUNC || HAVE_F_CHSIZE || HAVE_F_FREESP) */
  157. }
  158.